home *** CD-ROM | disk | FTP | other *** search
- /* Code from 86World column in Micro Cornucopia Issue #40 */
-
- /* KBDTEST.C - a progam to demonstrate interrupt 9 (the keyboard hardware
- interrupt) and test for proper operation of all keys on an
- IBM compatible keyboard.
-
- METHOD: The keyboard interrupt service vector is saved and replaced
- with a pointer to our own routine which simply prints a
- little message somewhere on the screen according to which
- key is pressed. By doing this, the screen can give a graphic
- display of which keys the computer thinks are pressed at any
- given time.
-
- If there is a difference between what is shown on the screen
- and what is pushed down on the keyboard, then the keyboard
- very likely has some design flaws, either in hardware or in
- the firmware on the keyboard MPU.
-
- COMPILING:Use the file kbdtest.prj as your project file, and MAKE
- SURE YOU USE A LARGE DATA MODEL!! The program works under
- compact and large, but it doesn't work under tiny, small,
- or medium. I haven't tried huge. Be sure to compile video.c
- with the same memory model.
-
- Required Files: KBDTEST.C, KBDTEST.PRJ, VIDEO.C, VIDEO.H,
- MCMVSMEM.OBJ, normal C libraries, etc.
-
- NOTES: Feel free to use any part of this program anywhere you like,
- with NO restrictions. Just remember me kindly.
-
- originally written in Pascal, Feb. 16, 1987
- translated from original into C, Dec 13, 1987
-
- Laine Stump, Dec 13, 1987
- */
- #include <dos.h>
- #include <stdarg.h> /* needed for va_arg in video.h */
- #include "video.h"
-
- #define ESCLIMIT 25 /* # of consec. ESC presses to mean "exit" */
- #define KEYLIMIT 83 /* higher for models w/F11 & F12 keys */
-
- struct
- {
- char message[6];
- unsigned char col, row;
- } keydisp[KEYLIMIT] = {
- {"Es",18,9}, {"1!",21,9}, {"2@",24,9}, {"3#",27,9}, {"4$",30,9},
- {"5%",33,9}, {"6^",36,9}, {"7&",39,9}, {"8*",42,9}, {"9(",45,9},
- {"0)",48,9}, {"-_",51,9}, {"=+",54,9}, {"<───",57,9},{"Tab",18,11},
- {"Qq",22,11}, {"Ww",25,11}, {"Ee",28,11}, {"Rr",31,11}, {"Tt",34,11},
- {"Yy",37,11}, {"Uu",40,11}, {"Ii",43,11}, {"Oo",46,11}, {"Pp",49,11},
- {"{[",52,11}, {"}]",55,11}, {"<┘",59,12}, {"Ctrl",18,13},{"Aa",23,13},
- {"Ss",26,13}, {"Dd",29,13}, {"Ff",32,13}, {"Gg",35,13}, {"Hh",38,13},
- {"Jj",41,13}, {"Kk",44,13}, {"Ll",47,13}, {":;",50,13}, {"\"'",53,13},
- {"~`",56,13}, {"LS",18,15}, {"|\\",21,15},{"Zz",24,15}, {"Xx",27,15},
- {"Cc",30,15}, {"Vv",33,15}, {"Bb",36,15}, {"Nn",39,15}, {"Mm",42,15},
- {"<,",45,15}, {">.",48,15}, {"?/",51,15}, {"RS",55,15}, {"PS",59,15},
- {"Alt",19,17}, {"Space",34,17}, {"Caps",54,17},{"F1",9,9}, {"F2",12,9},
- {"F3",9,11}, {"F4",12,11}, {"F5",9,13}, {"F6",12,13}, {"F7",9,15},
- {"F8",12,15}, {"F9",9,17}, {"F0",12,17}, {"Num",63,9}, {"Scrl",69,9},
- {"Hm",62,11}, {" ^",65,11}, {"Pu",68,11}, {" -",71,11}, {"< ",62,13},
- {" 5",65,13}, {" >",68,13}, {" +",71,15}, {"En",62,15}, {" v",65,15},
- {"Pd",68,15}, {"Ins",60,17}, {"Del",66,17}
- };
-
- /* static globals */
- int escctr;
- void interrupt (*int9save)(); /* a place to save address of old */
- /* interrupt handler */
-
- /* the routine that will be executed for every keypress */
- void interrupt int9service()
- /* a basic outline: read kbd data port
- act on the key
- strobe acknowledge of kbd control port
- signal end of interrupt to int controller
- return
- */
- {
- unsigned char scancode;
-
- /* should enable interrupts here, but I don't feel like
- getting out the command line version of the compiler
- for just one line of assembly (maybe it's already done??) */
-
- scancode = inportb(0x60); /* get input from keyboard */
- if ((scancode & 0x7F) == 1) /* check for ESC (scan code 1) */
- {
- if (scancode > 0x7F)
- escctr = 0;
- else
- escctr++;
- }
- /* display or undisplay a key */
- if (scancode > 0x7F)
- in(NORMAL);
- else
- in(REVERSE);
- scancode &= 0x7F;
- if ((scancode > 0) && (scancode <= KEYLIMIT))
- {
- scancode--; /* convert position to offset */
- at(keydisp[scancode].row,keydisp[scancode].col);
- cprintf("%s",keydisp[scancode].message);
- }
- else
- {
- at(20,39);
- cprintf("%2X",(int) scancode);
- }
- /* signal EOI to kbd & controller */
- outportb(0x61,inportb(0x61) | 0x80);
- outportb(0x61,inportb(0x61) & 0x7F);
- outportb(0x20,0x20);
- } /* int9service */
-
- void printkbd(void)
- /* put up a graphical representation of an IBM XT keyboard */
- {
- at(1,32); in(REVERSE); cprintf(" KBDTEST v1.1 ");
- in(NORMAL);
- at(8,8);
- cprintf("┌──┬──┐ ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬────┬─────┬─────┐");
- at(9, 8);
- cprintf("│F1│F2│ │Es│1!│2@│3#│4$│5%│6^│7&│8*│9(│0)│-_│=+│<───│ Num │ Scrl│");
- at(10,8);
- cprintf("├──┼──┤ ├──┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴─┬──┼──┬──┼──┬──┤");
- at(11,8);
- cprintf("│F3│F4│ │Tab│Qq│Ww│Ee│Rr│Tt│Yy│Uu│Ii│Oo│Pp│{[│}] │ │Hm│ ^│Pu│ -│");
- at(12,8);
- cprintf("├──┼──┤ ├───┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬──┤<┘├──┼──┼──┼──┤");
- at(13,8);
- cprintf("│F5│F6│ │Ctrl│Aa│Ss│Dd│Ff│Gg│Hh│Jj│Kk│Ll│:;│\"'│~`│ │< │ 5│ >│ │");
- at(14,8);
- cprintf("├──┼──┤ ├──┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴┬─┴──┼──┼──┼──┼──┤ │");
- at(15,8);
- cprintf("│F7│F8│ │LS│|\\│Zz│Xx│Cc│Vv│Bb│Nn│Mm│<,│>.│?/│ RS │PS│En│ v│Pd│ +│");
- at(16,8);
- cprintf("├──┼──┤ ├──┴─┬┴──┴──┴──┴──┴──┴──┴──┴──┴──┴─┬┴────┼──┴──┼──┴──┤ │");
- at(17,8);
- cprintf("│F9│F0│ │ Alt│ Space │ Caps│ Ins │ Del │ │");
- at(18,8);
- cprintf("└──┴──┘ └────┴─────────────────────────────┴─────┴─────┴─────┴──┘");
-
- at(22,23); in(REVERSE); cprintf(" hold down ESC for 3 sec. to Exit ");
- } /* printkbd */
-
- /*-------------------------*/
- main()
- {
- initvideo();
- printkbd();
-
- escctr = 0;
- int9save = getvect(9);
- setvect(9,int9service);
- while (escctr < ESCLIMIT) /* wait until the signal to end */
- ;
- setvect(9,int9save); /* restore old service so we don't have */
- in(NORMAL); clearscreen(); /* to reach for the BRS (Big Red Switch) */
- } /* main */